package auth

import (
	"net/http"
	"strings"

	"github.com/google/uuid"
	"github.com/labstack/echo/v4"
	"gorm.io/gorm"
	"techoiceness.com/aiagent/llm-gateway/internal/server/response"
)

// AuthMiddleware 认证中间件
type AuthMiddleware struct {
	jwtManager *JWTManager
	db         *gorm.DB
}

// NewAuthMiddleware 创建认证中间件
func NewAuthMiddleware(jwtManager *JWTManager, db *gorm.DB) *AuthMiddleware {
	return &AuthMiddleware{
		jwtManager: jwtManager,
		db:         db,
	}
}

type Authenticatable interface {
	GetID() uuid.UUID
	GetUsername() string
}

type AuthenticatableFactory func() Authenticatable

// JWT JWT认证中间件
func (a *AuthMiddleware) JWT(authFactory AuthenticatableFactory) echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			// 从Authorization header中获取token
			authHeader := c.Request().Header.Get("Authorization")
			if authHeader == "" {
				return echo.NewHTTPError(http.StatusUnauthorized, "missing authorization header")
			}

			// 检查Bearer前缀
			const bearerPrefix = "Bearer "
			if !strings.HasPrefix(authHeader, bearerPrefix) {
				return echo.NewHTTPError(http.StatusUnauthorized, "invalid authorization header format")
			}

			// 提取token
			tokenString := authHeader[len(bearerPrefix):]
			if tokenString == "" {
				return echo.NewHTTPError(http.StatusUnauthorized, "missing token")
			}

			// 验证token
			claims, err := a.jwtManager.ValidateToken(tokenString)
			if err != nil {
				return echo.NewHTTPError(http.StatusUnauthorized, "invalid token")
			}

			// 从数据库中获取用户信息
			account := authFactory()
			if err := a.db.First(account, claims.ID).Error; err != nil {
				if err == gorm.ErrRecordNotFound {
					return response.Unauthorized(c, "user not found")
				}
				return response.InternalServerError(c, "failed to retrieve user information")
			}

			// 将用户信息存储到context中
			c.Set("account", account)
			c.Set("accountID", account.GetID())

			return next(c)
		}
	}
}

// OptionalJWT 可选的JWT认证中间件（用于可能需要用户信息但不强制认证的接口）
func (a *AuthMiddleware) OptionalJWT(authFactory AuthenticatableFactory) echo.MiddlewareFunc {
	return func(next echo.HandlerFunc) echo.HandlerFunc {
		return func(c echo.Context) error {
			// 尝试获取token，但不强制要求
			authHeader := c.Request().Header.Get("Authorization")
			if authHeader != "" {
				const bearerPrefix = "Bearer "
				if strings.HasPrefix(authHeader, bearerPrefix) {
					tokenString := authHeader[len(bearerPrefix):]
					if tokenString != "" {
						// 尝试验证token
						if claims, err := a.jwtManager.ValidateToken(tokenString); err == nil {
							// 尝试获取用户信息
							account := authFactory()
							if err := a.db.First(account, claims.ID).Error; err == nil {
								c.Set("account", account)
								c.Set("accountID", account.GetID())
							}
						}
					}
				}
			}

			return next(c)
		}
	}
}
